package aichess;

import java.util.concurrent.TimeUnit;

/**
 * Class that implements Iterative Deepening DFS
 * @author DumbStation
 */
public class IDS {
    private static int nodes = 0;
    private static long start = 0;
    private static long finish = 0;
    private static MoveValue mv;
    
    /**	ids: checks with minimax the moves of the pieces and if there is a checkmate in the search-tree (until the limit).
    *	@param board board to analyze.
    *   @param limit limit of ids, here stop searching in that branch of the tree. 
    **/
    public static MoveValue ids(Board board, int limit){
        mv = new MoveValue();
        start = System.nanoTime();
        if(!board.isCheckMate() || !board.isStalemate()){
            Move[] movements = board.getValidMoves();
            for(Move a:movements){
                Board clone = board.clone();
                clone.makeMove(a);
                nodes++;
                mv.setMove(a);
                mv.setValue(minimax(clone, limit));
            }
        }
        finish = System.nanoTime();
        System.out.println("Expanded nodes: " + nodes);
        System.out.println("Elapsed time: " + TimeUnit.MILLISECONDS.convert(finish-start, TimeUnit.NANOSECONDS) + "ms");
        return mv;
    }
    
    /**	IDS version of minimax, limited.
    *	@param board board to analyze.
    *   @param limit limit of ids, here stop searching in that branch of the tree. 
    **/
    public static int minimax(Board board, int limit){
        int max = -99999;
        
        if(!(limit <= 0)){
            if(!board.isStalemate() || !board.isCheckMate() && board.movestodraw >= 1 && limit > 0){
                Move[] movements = board.getValidMoves();
                for(Move a:movements){
                    Board clone = board.clone();
                    clone.makeMove(a);
                    nodes++;
                    mv.setMove(a);
                    int minmax = -(minimax(clone, limit--));
                    if(max > minmax){
                        mv.setValue(max);
                        return max;
                    }
                    mv.setValue(minmax);
                    return minmax;
                }
            }
            if(board.isCheckMate()){
                return 1;
            }
            if(board.isStalemate()){
                return 0;
            }
        }
        return 0;
    }
}
